/*
 * Platzad
 * Copyright 2008 Shayne Riley
 *
 * This file is part of Platzad.
 *
 * Platzad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Platzad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Platzad.  If not, see <http://www.gnu.org/licenses/>.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <shayner at gmail dot com> or write to
 * Shayne Riley / P.O. Box 1092 / McCook, NE 69001.
 */

#ifndef GAME_H_
#define GAME_H_

#include "../display/Display.h"
#include "../display/ImageSDL.h"
#include "../control/InputHandler.h"
#include "../control/InputEntry.h"
#include <iostream>

namespace pzdLogic
{

//! The game.
/**
 * This is where the main game action takes place.
 *
 * It is fairly straight-forward at this point. Call the playGame() method.
 */
class Game
{
    public:
        void playGame();

        //! Constructor for the logic sub-system.
    	/**
    	 * There should only be one logic-subsystem. Making the constructor
    	 * private ensures this happens.
    	 */
    	Game();

        //! Destructor for a class that will never be derived from.
        ~Game();

    private:

        //! Does all the initialization for the class.
        void init();

        //! Does all the cleaning up and such for the class.
        void finalize();

        //! Retrieves the display to be used by the entire class.
        /**
         * Should only be used by the constructor.
         */
        void getDisplay();

        //! No copying needed, do not allow. Copy ctor declared, not defined.
        Game(const Game& rhs);
        //! No assignment needed. Do not define this function.
        Game& operator=(const Game rhs);
        //! No address-of needed. Do not define this function.
        Game* operator&();
        //! No const address-of needed. Do not define this function.
        const Game* operator&() const;

        void doMovementStuff();

        //! The display is the visualization of the game.
        pzdDisplay::Display display;

        //! The background is a sprite at this point. Baby Steps!
        const pzdDisplay::ImageSDL * background;

        //! The actor is a sprite at this point. Baby Steps!
        const pzdDisplay::ImageSDL * actor;

    	class Movement : public pzdControl::InputHandler
        {
        public:
        	Movement()
        	: mMoveRight(false), mMoveLeft(false), mMakeNoise(false), mQuit(false)
        	{}

        	virtual void operator()(pzdControl::InputEntry& entry)
        	{
        		switch(entry.getId())
        		{
        		case 114: // If right key...
        		case 40:  // or 'D' key, then user altered 'move right' state.
        			mMoveRight = entry.getState();
        			break;
        		case 113: // If left key...
        		case 38:  // or 'A' key, then user altered 'move left' state.
        			mMoveLeft = entry.getState();
        			break;
        		case 116: // If down key...
        		case 39:  // or 'S' key, then user wants to make noise.
        			mMakeNoise = entry.getState();
        			break;
        		case pzdControl::InputEntry::QUIT:
        			mQuit = entry.getState();
        		}
        		std::cout << entry.getId() << " " << entry.getState() << std::endl;
        	}

        	bool moveRight()
        	{
        		return mMoveRight;
        	}

        	bool moveLeft()
        	{
        		return mMoveLeft;
        	}

        	bool makeNoise()
        	{
        		// Ensure it is only done once per press.
        		if(mMakeNoise)
        		{
        			mMakeNoise = false;
        			return true;
        		}
        		return false;
        	}

        	bool quit()
        	{
        		return mQuit;
        	}
        private:
        	bool mMoveRight;
        	bool mMoveLeft;
        	bool mMakeNoise;
        	bool mQuit;
        };

        Movement movement;
};

} // namespace

#endif /*GAME_H_*/
